import { NonDirectGraph } from './无向图';
import { DirectGraph } from './有向图';

describe('NonDirectGraph Test', () => {
    const nG = new NonDirectGraph<string>();// 无向图对象

    test('Add VertexA to NonDirectGraph', () => {
        expect(nG.addVertex('A')).toBe(true);
    });

    test('VertexB not exists in NonDirectGraph', () => {
        expect(nG.hasVertex('B')).toBe(false);
    });

    test('Add VertexB-I to NonDirectGraph', () => {
        const strs = ['B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'];
        strs.forEach((str) => {
            expect(nG.addVertex(str)).toBe(true);
        })
    });

    test(('Vertexes exists in NonDirectGraph'), () => {
        // 需要检查内部结构，故断言成any
        expect((nG as any).vertexes).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']);
        const expectedMap = new Map<string, string[]>();
        expectedMap.set('A', [])
            .set('B', [])
            .set('C', [])
            .set('D', [])
            .set('E', [])
            .set('F', [])
            .set('G', [])
            .set('H', [])
            .set('I', []);
        expect((nG as any).adjList).toEqual(expectedMap);
    });

    test('Add correct connections to NonDirectGraph', () => {
        const connections: [string, string][] = [["A", "B"], ["A", "C"], ["A", "D"], ["C", "D"], ["C", "G"],
        ["D", "G"], ["D", "H"], ["B", "E"], ["B", "F"], ["E", "I"]];
        connections.forEach(([vA, vB]) => {
            expect(nG.addConnection(vA, vB)).toBe(true);
        })
    });

    test('Add uncorrect connection to NonDirectGraph', () => {
        expect(nG.addConnection('E', 'M')).toBe(false);
    });

    test('Cal minDistance in NonDirectGraph', () => {
        expect(nG.getMinDistance('A', 'I')).toBe(3);
        expect(nG.getMinDistance('A', 'A')).toBe(0);
        expect(nG.getMinDistance('C', 'D')).toBe(1);
        expect(nG.getMinDistance('H', 'A')).toBe(2);
    });

    test('Show the strcture of NonDirectGraph', () => {
        nG.show();
    })

    test('Show BFS outcome of NonDirectGraph', () => {
        const res: string[] = [];
        nG.bfs('A', (value) => res.push(value));
        expect(res).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']);
    })
})

describe('DirectGraph Test', () => {

    const graph = new DirectGraph<string>("A", "B", "C", "D", "E", "F", "G", "H", "I")

    test('Initial graph with params', () => {
        expect(graph).toMatchObject({
            vertexes: ["A", "B", "C", "D", "E", "F", "G", "H", "I"],
            adjList: expect.any(Map),
        })
    });

    test('Initial graph without params', () => {
        expect(new DirectGraph<string>())
            .toMatchObject({
                vertexes: expect.any(Array),
                adjList: expect.any(Map),
            })
    });

    test('Type detection', () => {
        expect(Object.prototype.toString.call(graph)).toBe('[object DirectGraph]');
    })

    test('Add correct connections to DirectGraph', () => {
        const connections: [string, string][] = [["A", "B"], ["A", "C"], ["A", "D"], ["C", "D"], ["C", "G"],
        ["D", "G"], ["D", "H"], ["B", "E"], ["B", "F"], ["E", "I"]];
        connections.forEach(([vA, vB]) => {
            expect(graph.addConnection(vA, vB)).toBe(true);
        })
    });

    test('DFS recursion the strcture of DirectGraph', () => {
        graph.dfs('A');
    });

    test('Cal minDistance in DirectGraph', () => {
        expect(graph.getMinDistance('A', 'G')).toBe(2);
        expect(graph.getMinDistance('G', 'A')).toBe(-1);
        expect(graph.getMinDistance('E', 'I')).toBe(1);
        expect(graph.getMinDistance('A', 'H')).toBe(2);
        expect(graph.getMinDistance('A', 'I')).toBe(3);
        expect(graph.getMinDistance('I', 'B')).toBe(-1);
    });

});

